App.require([], function () {
    var app = App.getCurrent();
    var height = 44;
    app.definePage("areaselectactive", {
        render: function (next) {
            this.parent.getOriginData(this.parent.data.initValue, function (options) {
                this.data.options = options;
                for (var i = 0; i < this.data.options.length; i++) {
                    var option = this.data.options[i];
                    option.index = option.index || 1;
                    option.cssStr = "transform: translateY(" + ((1-option.index) * 44) + "px)";
                }
                if (location.protocol !== "file:") {
                    this.fetch("./index.html", function (text) {
                        next(this.renderHTML(text));
                    });
                }
                else next(this.renderHTML(App.staticHtml.areaselectIndexHtml));
            }.bind(this));
        },
        getDomObj: function () {
            this.attachDom(".area-container", "container")
                .attachEvent("container", "touchstart", this.touchstartHandler, false)
                .attachEvent("container", "touchmove", this.touchmoveHandler, false)
                .attachEvent("container", "touchend", this.touchendHandler, false)
                .attachEvent("container", "click", this.clickHandler, false);
        },
        init: function () {
            this.data.animationArray = [];
            for (var i = 0; i < this.data.options.length; i++) {
                this.data.animationArray.push(new Animation(10, 0, Animation.normal));
            }
        },
        dispose: function () {
            this.data.animationArray.length = 0;
        },
        touchstartHandler: function (ev) {
            if (ev.touches.length > 1) return this._cancelMove();
            var target = ev.target;
            var ul = Component.getNodeName(target, "UL");
            if (ul) {
                this.domList.activeUl = ul;
                this.data.index = parseInt(ul.dataset.index) - 1
                this.data.touchstart = true;
                this.data.startTime = Date.now();
                if (!ul.style.transform) this.data.startY = 0;
                else {
                    var pattern = /translateY\((-?\d+\.?\d+?)px\)/;
                    var match = pattern.exec(ul.style.transform);
                    if (match) {
                        this.data.startY = parseInt(match[1]);
                    } else {
                        this.data.startY = 0;
                    }
                }
                var touch = ev.touches[0];
                this.data.touchY = touch.clientY;
            }
        },
        touchmoveHandler: function (ev) {
            ev.preventDefault();
            ev.stopPropagation();
            if (ev.touches.length > 1 || !this.domList.activeUl) return this._cancelMove();
            if (this.data.touchstart) this.domList.activeUl.style.transition = "none";
            this.data.touchmove = true;
            var touch = ev.changedTouches[0];
            var currentY = touch.clientY;
            var changeY = currentY - this.data.touchY;
            var transformY = this.data.startY + changeY;
            this.data.lastY = currentY;
            transformY = this.wrapHeight(transformY, this.domList.activeUl);
            this.domList.activeUl.style.transform = "translateY(" + transformY + "px)";
        },
        wrapHeight: function (h, ul) {
            var min = -(ul.children.length - 5) * height,
                max = 0;
            if (h > max) h = max;
            if (h < min) h = min;
            return h;
        },
        touchendHandler: function (ev) {
            if (!this.domList.activeUl || !this.data.touchmove) return false;
            ul = this.domList.activeUl;
            var transform = ul.style.transform,
                transformY = 0,
                that = this;
            var pattern = /translateY\((-?\d+\.?\d+?)px\)/;
            var match = pattern.exec(transform);
            if (match) {
                var ellapsed = Date.now() - this.data.startTime,
                    durationY = this.data.lastY - this.data.touchY,
                    index = this.data.index,
                    animation = this.data.animationArray[index],
                    startTop = parseInt(match[1]),
                    speed = durationY * 1000 / ellapsed;

                animation.ended = false;
                animation.onUpdate(function (value) {
                    if (Math.abs(speed) < 10) {
                        this.ended = true;
                        transformY = Math.abs(Math.round(startTop / height));
                        setTimeout(function () {
                            ul.style.transform = "translateY(-" + transformY * height + "px)";
                            that._addlist(transformY + 1, ul, ul.children[transformY + 2])
                        }, 0);
                    }
                    else {
                        speed *= 0.9;
                        startTop += parseInt(speed) / 60;
                        startTop = that.wrapHeight(startTop, ul);
                        ul.style.transform = "translateY(" + startTop + "px)";
                    }
                });
                this.addAnimation(animation);
            } else {
                ul.style.transform = "translateY(0px)";
                that._addlist(transformY + 1, ul, ul.children[transformY + 2])
            }

            this._cancelMove();

        },
        _cancelMove: function () {
            if (!this.domList.activeUl) return;
            this.domList.activeUl.style.removeProperty("transition");
            this.domList.activeUl = null;
            this.data.touchstart = false;
            this.data.touchmove = false;
            this.data.startTime = null;
            this.data.lastY = null;
            this.data.index = 0;
            this.data.touchY = 0;
            this.data.startY = 0;
        },
        _addlist: function (index, ul, li) {
            var that = this;
            var ii = parseInt(ul.dataset.index) - 1;
            this.data.options[ii].index = index;
            ul.style.setProperty("transform", "translateY(" + (1 - index) * height + "px)");
            var index = parseInt(ul.dataset.index);
            if (index === this.data.options.length) return;
            else {
                if (typeof this.parent.getNextData !== "function") return;
                this.parent.getNextData(index, li.dataset.value, this._getPrevList(index), function (data) {
                    this.data.options[index].items = data;
                    var nextUl = ul.parentNode.children[index];
                    this.innerHTML(nextUl, '<li></li><li></li>{{each item as items}}' +
                        '<li data-index="{{item.index}}" data-value="{{item.value}}">{{item.content}}</li>{{/each}}<li></li><li></li>',
                        function () {
                            var ii = parseInt(nextUl.dataset.index) - 1;
                            var index = that.data.options[ii].index;
                            if (index > data.length) index = data.length;
                            that._addlist(index, nextUl, nextUl.children[2]);
                        }, {
                            items: data
                        }
                    );
                }.bind(this));
                
            }
        },
        _getPrevList: function (index) {
            var data =  [], container = this.domList.container;
            for (var i = 0; i < index; i++) {
                var ul = container.children[i], transform = ul.style.transform;
                var match = /translateY\((-?\d+\.?\d+?)px\)/.exec(transform);
                if (match) {
                    var j = Math.abs(parseInt(match[1]) / 44);
                    data.push(this.data.options[i].items[j].value);
                }
                else {
                    data.push(this.data.options[i].items[0].value);
                }
            }
            return data;
        },
        clickHandler: function (ev) {
            var li = Component.getNodeName(ev.target, "LI");
            if (li && li.dataset.index) {
                var index = parseInt(li.dataset.index),
                    ul = li.parentNode;
                this._addlist(index, ul, li)
            }
        },
        getSelectData: function () {
            var container = this.domList.container,
                uls = container.children;
            var result = [];
            var pattern = /translateY\((-?\d+\.?\d+?)px\)/;
            for (var i = 0; i < uls.length; i++) {
                var ul = uls[i],
                    transform = ul.style.transform;
                var match = pattern.exec(transform);
                if (match) {
                    var index = Math.abs(parseInt(match[1]) / 44);
                    result.push(this.data.options[i].items[index]);
                } else {
                    result.push(this.data.options[i].items[0]);
                }
            }
            return result;
        }
    })
})